/*
 * Copyright (c) 2009 Sun Microsystems, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **/

package com.sun.spot.wot;

import com.sun.spot.ipv6.tcp.Socket;
import com.sun.spot.espot.peripheral.ota.URL;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;
import com.sun.spot.wot.http.HttpRequest;
import com.sun.spot.wot.http.HttpResponse;

/**
 *
 * @author vgupta
 */
public class SPOTRHTTPHandler extends Thread {
    private int MAX_HEADER_SIZE = 1024;
    private URL url = null;
    private Socket sock = null;
    private NanoAppServer ar = null;

    public SPOTRHTTPHandler(String url, NanoAppServer ar) {
        this.url = new URL(url);
        this.ar = ar;
    }

    public void run() {
        HttpRequest req = new HttpRequest();
        HttpRequest innerReq = new HttpRequest();
        HttpResponse res = new HttpResponse();
        HttpResponse innerRes = new HttpResponse();
        InputStream is = null;
        OutputStream os = null;
        byte[] buf = null;
        SocketConnection sc = null;

        System.out.println("Starting SPOTRHTTP handler ... ");
        while (true) {
            try {
                Thread.sleep(2000);
                // Open up an HTTP connection to the URL
                sc = (SocketConnection)
                        Connector.open("socket://" + "sensor.network.com:1234");
//                        url.getAddress() + ":" +
//                        url.getPort());

                is = sc.openInputStream();
                os = sc.openOutputStream();

                System.out.println("Connected to " + "sensor.network.com:1234");
//                        url.getAddress() + ":" +
//                        url.getPort());

//                req.setMethod("POST");
//                req.setPathInfo(url.getAddress());
//                req.setHeader("Upgrade", "PTTH/1.0");
//                req.setHeader("Connection", "Upgrade");
//                req.setHeader("Host", url.getAddress());
//                buflen = req.toByteArray(false, buf, 0);
//                System.out.println("Sent request\n" + req);
//                os.write(buf, 0, buflen);

                String reqStr = "POST " + "/warn" + " HTTP/1.1\r\n" +
                        "Upgrade: PTTH/1.0\r\n" +
                        "Connection: Upgrade\r\n" +
                        "Host: " + url.getAddress() + "\r\n\r\n";
                System.out.println("Sending request\n" + reqStr);
                os.write(reqStr.getBytes());

                os.flush();
                System.out.println("Waiting for response ...");
                res.parse(is);
                System.out.println("Got response\n" + res);
                if (res.getStatus() == HttpResponse.SC_SWITCHING_PROTOCOLS) {
//                    byte[] tunneledReqBytes = res.getBody();
//                    if (tunneledReqBytes != null) {
//                        innerReq = HttpRequest.parse(tunneledReqBytes,
//                                0, tunneledReqBytes.length);
//                        System.out.println("Inner request is\n" + innerReq);
                        boolean haveInnerReq = false;
                        try {
                            innerReq.parse(is);
                            innerRes = ar.getResponse(innerReq);
                            haveInnerReq = true;
                        } catch (Exception e) {
                            System.out.println("Could not parse inner request");
                            e.printStackTrace();
                            innerRes.setStatus(HttpResponse.SC_BAD_REQUEST);
                        }

                        buf = new byte[(res.getBody() == null? 0:res.getBody().length) +
                                MAX_HEADER_SIZE];
                        int wlen = innerRes.toByteArray((haveInnerReq &&
                            innerReq.isCompressed()), buf, 0);

                        System.out.println("Inner response is:\n" + innerRes);
                        os.write(buf, 0, wlen);
                        os.flush();
//                    }
                }
            } catch (Exception ex) {
                System.err.println("Caught " + ex);
                ex.printStackTrace();
            } finally {

                try {
                    System.out.println("Closing reversehttp connection to " +
                            "sensor.network.com:1234"); //127.0.0.1:8080");
//                            url.getAddress() + ":" + url.getPort());
                    if (is != null) is.close();
                    if (os != null) os.close();
                    if (sc != null) sc.close();
//                    sock.close();
                } catch (IOException ex) {
                    System.err.println("Caught " + ex);
                    ex.printStackTrace();
                }
            }
        }
    }
}
